
package com.ciei.dpagm.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.ciei.dpagm.common.enums.ErrorCodeEnum;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Map;

public class JsonUtil {

	public final static String SUCCESS = "success";

	public final static String MESSAGE = "message";

	public static String replacedNullToFaultString(String jsonStr, String replacedString) {
		JSONObject jsonObject = JSONObject.parseObject(jsonStr);
		for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
			if (entry.getValue() == null) {
				entry.setValue(replacedString);
			}
		}
		return jsonObject.toJSONString();
	}

	public static JSONObject getFail(String message) {
		JSONObject json = new JSONObject();
		json.put(SUCCESS, false);
		json.put(MESSAGE, message);
		return json;
	}

	/**
	 * 生成“失败”返回值模板
	 * @param errorCodeEnum		错误码枚举
	 * @return					“失败”返回值模板
	 */
	public static JSONObject getFail(ErrorCodeEnum errorCodeEnum) {
		return getFail(errorCodeEnum, null);
	}

	/**
	 * 生成“失败”返回值模板
	 * @param errorCodeEnum		错误码枚举
	 * @param message			自定义信息
	 * @return					“失败”返回值模板
	 */
	public static JSONObject getFail(ErrorCodeEnum errorCodeEnum, String message) {
		JSONObject json = new JSONObject();
		json.put(SUCCESS, false);
		json.put(APP.ERROR_CODE, errorCodeEnum.getErrorCode());
		if (message == null) {
			json.put(MESSAGE, errorCodeEnum.getDescription());
		} else {
			json.put(MESSAGE, message);
		}
		return json;
	}

	public static JSONObject getSuccess(String message) {
		JSONObject data = new JSONObject();
		data.put(SUCCESS, true);
		data.put(MESSAGE, message);
		data.put(APP.ERROR_CODE, 0);
		return data;
	}


	/**
	 * 导出JSON子字符串，仅包含includeProperties中的属性
	 *
	 * @param object            转换对象
	 * @param includeProperties 包含属性列表
	 * @return JSON子字符串
	 */
	public static String toJsonStringIncludeProperties(Object object, String[] includeProperties) {
		PropertyFilter propertyFilter = (object1, name, value) -> {
			if (includeProperties == null || includeProperties.length == 0) {
				return true;
			}
			for (String pName : includeProperties) {
				if (name.equalsIgnoreCase(pName)) {
					return true;
				}
			}
			return false;
		};

		return JSONObject.toJSONString(object, propertyFilter);
	}

	/**
	 * 导出JSON子字符串，忽略exceptProperties中的属性
	 *
	 * @param object           转换对象
	 * @param exceptProperties 忽略属性列表
	 * @return JSON子字符串
	 */
	public static String toJsonStringExceptProperties(Object object, String[] exceptProperties) {
		PropertyFilter propertyFilter = (object1, name, value) -> {
			if (value == null) {
				return false;
			}
			if (exceptProperties == null || exceptProperties.length == 0) {
				return true;
			}
			for (String pName : exceptProperties) {
				if (name.equalsIgnoreCase(pName)) {
					return false;
				}
			}
			return true;
		};

		return JSONObject.toJSONString(object, propertyFilter);
	}

	/**
	 * 将对象序列化成JSON字符串，仅包含includeFields中的属性字段<br/>
	 * (PS：使用{@link SimplePropertyPreFilter#getIncludes()} 方法配置的filter只能序列化第一层，对于多层嵌套的对象无效 )
	 *
	 * @param object        转换对象
	 * @param includeFields 包含字段列表
	 * @return JSON字符串
	 */
	public static String toJsonStringIncludes(Object object, String[] includeFields) {
		if (includeFields != null && includeFields.length > 0) {
			SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
			for (String field : includeFields) {
				filter.getIncludes().add(field);
			}
			SerializeFilter[] filters = {filter};
			// 空值不忽略
			return JSON.toJSONString(object, filters, SerializerFeature.WriteMapNullValue);
		}
		return JSON.toJSONString(object, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty);
	}

	/**
	 * 将对象序列化成JSON字符串，过滤excludeFields中的属性字段<br/>
	 * (PS：使用{@link SimplePropertyPreFilter#getIncludes()} 方法配置的filter只能序列化第一层，对于多层嵌套的对象无效 )
	 *
	 * @param object        转换对象
	 * @param excludeFields 过滤字段列表
	 * @return JSON字符串
	 */
	public static String toJsonStringExcludes(Object object, String[] excludeFields) {
		if (excludeFields != null && excludeFields.length > 0) {
			SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
			for (String field : excludeFields) {
				filter.getExcludes().add(field);
			}
			SerializeFilter[] filters = {filter};
			// 空值不忽略
			return JSON.toJSONString(object, filters, SerializerFeature.WriteMapNullValue);
		}
		return JSON.toJSONString(object, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty);
	}



	public static JSONObject readJsonFile(String path) {
		// path=json/deviceConfig.json
		try {
			ClassPathResource classPathResource = new ClassPathResource(path);
			InputStream inputStream =classPathResource.getInputStream();
			String jsonText  = IOUtils.toString(inputStream, Charset.forName("UTF-8"));
			return JSON.parseObject(jsonText);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

}
